From 2e59f67796a3a5a1042d04bcd11b9e966a3a23ca Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 15 Jul 2004 21:29:58 +0000 Subject: [PATCH] bitkeeper revision 1.1099 (40f6f756_UAMBuGEnf4DcZB7Z3xbwg) Truncate TLS segments to avoid overlap with Xen private area. --- .../arch/xen/i386/kernel/process.c | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c index 1d7f637a66..320b181f8c 100644 --- a/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c +++ b/linux-2.6.7-xen-sparse/arch/xen/i386/kernel/process.c @@ -331,6 +331,24 @@ void prepare_to_copy(struct task_struct *tsk) unlazy_fpu(tsk); } +/* NB. This Xen-specific function is inlined in 'write_ldt'. */ +static int truncate_user_desc(struct user_desc *info) +{ + unsigned long max_limit; + + if (info->base_addr >= PAGE_OFFSET) + return 0; + + max_limit = HYPERVISOR_VIRT_START - info->base_addr; + if (info->limit_in_pages) + max_limit >>= PAGE_SHIFT; + max_limit--; + if ((info->limit & 0xfffff) > (max_limit & 0xfffff)) + info->limit = max_limit; + + return 1; +} + int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, unsigned long unused, struct task_struct * p, struct pt_regs * regs) @@ -381,6 +399,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) goto out; + if (!truncate_user_desc(&info)) + goto out; + desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; desc->a = LDT_entry_a(&info); desc->b = LDT_entry_b(&info); @@ -696,6 +717,9 @@ asmlinkage int sys_set_thread_area(struct user_desc __user *u_info) return -EFAULT; idx = info.entry_number; + if (!truncate_user_desc(&info)) + return -EINVAL; + /* * index -1 means the kernel should try to find and * allocate an empty descriptor: -- 2.30.2